package com.ithinks.flow.common.utils.protocol.http.URLConnetion;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.*;
import java.io.*;
import java.net.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * @Description 向固定的url资源发起请求。
 * URLConnection是HTTPURLConnection的超类。否则增加了HTTP相关的参数设置
 * @ClassName URLConnectionUtils
 * @Author MR.LI
 * @date 2020.12.04 13:45
 */
public class URLConnectionUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(URLConnectionUtils.class);

    /**
     * HTTP 发送get请求
     * @param url
     * @param param
     * @return
     */
    public static String sendGet(String url,String param){
        StringBuilder result = new StringBuilder();
        BufferedReader in = null;

        String urlNameString = url+"?"+param;
        LOGGER.info("sendGet-{}",urlNameString);
        try {
            URL realUrl = new URL(urlNameString);
            URLConnection connection = realUrl.openConnection();
            //接收格式设置
            connection.setRequestProperty("accept","*/*");
            // 当一个网页打开完成后，客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭，如果客户端再次访问这个服务器上的网页，会继续使用这一条已经建立的连接。
            connection.setRequestProperty("connection","Keep-Alive");
            //告诉HTTP服务器，客户端使用的操作系统和浏览器的名称和版本。
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while((line = in.readLine()) !=null){
                result.append(line);
            }
            LOGGER.info("recivice-{}",result);
        }
        catch (ConnectException e)
        {
            LOGGER.error("调用URLConnectionUtils.sendGet ConnectException, url=" + url + ",param=" + param, e.getMessage());
        }
        catch (SocketTimeoutException e)
        {
            LOGGER.error("调用URLConnectionUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e.getMessage());
        }
        catch (IOException e)
        {
            LOGGER.error("调用URLConnectionUtils.sendGet IOException, url=" + url + ",param=" + param, e.getMessage());
        }
        catch (Exception e)
        {
            LOGGER.error("调用URLConnectionUtils.sendGet Exception, url=" + url + ",param=" + param, e.getMessage());
        }
        finally
        {
            try
            {
                if (in != null)
                {
                    in.close();
                }
            }
            catch (Exception ex)
            {
                LOGGER.error("调用in.close Exception, url=" + url + ",param=" + param, ex.getMessage());
            }
        }
        return result.toString();
    }

    /**
     * 向指定url发送http post请求
     * @return
     */
    public static String sendPost(String url,String param){
        PrintWriter out = null;
        BufferedReader in= null;
        StringBuilder result = new StringBuilder();
        String urlNameString = url+"?"+param;
        LOGGER.info("sendGet-{}",urlNameString);
        try {
            URL realUrl = new URL(urlNameString);
            URLConnection conn = realUrl.openConnection();
            conn.setRequestProperty("accept","*/*");
            conn.setRequestProperty("connection","Keep-Alive");
            conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset","UTF-8");
            conn.setRequestProperty("contentType","UTF-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            out = new PrintWriter(conn.getOutputStream());
            out.print(param);
            out.flush();
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
            String line;
            while((line = in.readLine()) !=null){
                result.append(line);
            }
            LOGGER.info("recv - {}",result);
        }
        catch (ConnectException e)
        {
            LOGGER.error("调用URLConnectionUtils.sendPost ConnectException, url=" + url + ",param=" + param, e.getMessage());
        }
        catch (SocketTimeoutException e)
        {
            LOGGER.error("调用URLConnectionUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e.getMessage());
        }
        catch (IOException e)
        {
            LOGGER.error("调用URLConnectionUtils.sendPost IOException, url=" + url + ",param=" + param, e.getMessage());
        }
        catch (Exception e)
        {
            LOGGER.error("调用URLConnectionUtils.sendPost Exception, url=" + url + ",param=" + param, e.getMessage());
        }
        finally
        {
            try
            {
                if (out != null)
                {
                    out.close();
                }
                if (in != null)
                {
                    in.close();
                }
            }
            catch (IOException ex)
            {
                LOGGER.error("调用in.close Exception, url=" + url + ",param=" + param, ex.getMessage());
            }
        }
        return result.toString();
    }

    /**
     * 使用urlConnection发起SSL加密请求
     * @param url
     * @param param
     * @return
     */
    public static String sendSslPost(String url,String param){
        StringBuilder result = new StringBuilder();
        String urlNameString = url + "?" +param;
        LOGGER.info("sendSSLPost-{}",urlNameString);
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null,new TrustManager[]{new TrustAnyTrustManager()},new java.security.SecureRandom());
            URL url1 = new URL(urlNameString);
            HttpsURLConnection connection = (HttpsURLConnection) url1.openConnection();
            connection.setRequestProperty("accept","*/*");
            connection.setRequestProperty("connection","Keep-Alive");
            connection.setRequestProperty("use-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.setRequestProperty("contentType","utf-8");
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setSSLSocketFactory(sc.getSocketFactory());
            connection.setHostnameVerifier(new TrustAnyHostnameVerifier());
            connection.connect();
            InputStream is = connection.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String read = "";
            while((read = br.readLine()) != null){
                if(read !=null && !"".equals(read.trim())){
                    result.append(new String(read.getBytes()));
                }
            }
            connection.disconnect();
            br.close();
        } catch (NoSuchAlgorithmException e) {

            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result.toString();
    }

    private static class TrustAnyTrustManager implements X509TrustManager {

        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }
    }

    private static class TrustAnyHostnameVerifier implements HostnameVerifier{

        @Override
        public boolean verify(String s, SSLSession sslSession) {
            return true;
        }
    }


}
